package com.d2rv.guide;

import com.d2rv.model.GoalModel;
import com.d2rv.offscreen.OffScreen3D;
import java.util.LinkedList;
import processing.core.PVector;

/**
 * This class extends Goal and displays a list of successive directions to
 * follow.
 *
 * @author Darrieutort A., Dupouy A., Rossignol L., Van Poucke A.
 */
public class GoalCourse extends Goal {

    private LinkedList<PVector> positions;

    /**
     * Default constructor.
     *
     * @param model
     */
    public GoalCourse(GoalModel model) {
        super(model);
        this.positions = new LinkedList<PVector>();
    }

    /**
     * Initializes the course by clearing the list of positions.
     */
    public void init() {
        this.positions.clear();
    }

    /**
     * Returns the position of the first position to follow.
     *
     * @return the position of the first position to follow, null if empty
     */
    public PVector position() {
        if (!this.positions.isEmpty()) {
            return this.positions.getFirst();
        }
        return null;
    }

    /**
     * Add a new position to follow at the end of the list.
     *
     * @param position a new position to follow
     */
    public void position(PVector position) {;
        this.positions.addLast(position);
        this.model.position(this.positions.getFirst());
    }

    /**
     * Deletes the first position of the list.
     */
    private void deletePosition() {
        if (!this.positions.isEmpty()) {
            this.positions.pollFirst();
        }
        if (!this.positions.isEmpty()) {
            this.model.position(this.positions.getFirst());
        }
    }

    /**
     * Draws the goal model.
     *
     * @param parent the current offscreen
     */
    public void draw(OffScreen3D parent) {
        if (!this.positions.isEmpty()) {
            parent.pushMatrix();
            parent.translate(this.positions.getFirst().x, this.positions.getFirst().y, this.positions.getFirst().z);
            this.model.draw(parent);
            parent.popMatrix();
        }
    }

    /**
     * Draws the goal model on the guide offscreen, the color of the model
     * changes with the user position.
     *
     * @param parent the current offscreen
     * @param userpos the user position
     */
    public void drawGuide(OffScreen3D parent, PVector userpos) {
        if (!this.positions.isEmpty()) {
            double dfirst = 0, d = 0;
            int i = 0;
            for (PVector p : this.positions) {
                if (i == 0) {
                    dfirst = Math.sqrt((p.x - userpos.x) * (p.x - userpos.x) + (p.z - userpos.z) * (p.z - userpos.z));
                }
                d = Math.sqrt((p.x - userpos.x) * (p.x - userpos.x) + (p.z - userpos.z) * (p.z - userpos.z));
                parent.pushMatrix();
                parent.translate(p.x, p.y, p.z);
                if (d < 150) {
                    this.model.changeSphere(1);
                } else if (d >= 150 && d < 350) {
                    this.model.changeSphere(2);
                } else if (d >= 350) {
                    this.model.changeSphere(3);
                }
                this.model.draw(parent);
                if (dfirst < 150) {
                    this.model.changeSphere(1);
                } else if (dfirst >= 150 && dfirst < 350) {
                    this.model.changeSphere(2);
                } else if (dfirst >= 350) {
                    this.model.changeSphere(3);
                }
                parent.popMatrix();
                i++;
            }
        }
    }

    /**
     * Deletes the first position of the list to follow to follow the next one.
     */
    public void goalAchieved() {
        this.deletePosition();
    }
}